from typing import Any, Dict, Type

from .base_node import BaseNode
from .start_node import StartNode
from .condition_node import ConditionNode
from .http_request_node import HttpRequestNode
from .task_assignment_node import TaskAssignmentNode
from .end_node import EndNode
from .llm_node import LLMNode
from .agent_node import AgentNode
from .wait_node import WaitNode
from .rag_node import RAGNode
from .message_node import MessageNode
from .tool_node import ToolNode
from .memory_node import MemoryNode


class NodeFactory:
    """
    节点工厂类（单一职责：根据流程 JSON 中的节点类型创建具体节点对象）。
    
    设计说明：
    - 通过 TYPE_MAP 映射类型字符串到具体类
    - 保持输入输出结构与原始 JSON 一致（若提供则填充）
    - 仅负责对象创建，不承担执行逻辑
    """
    TYPE_MAP: Dict[str, Type[BaseNode]] = {
        'start': StartNode,
        'condition': ConditionNode,
        'httpRequest': HttpRequestNode,
        'taskAssignment': TaskAssignmentNode,
        'end': EndNode,
        'llm': LLMNode,
        'agent': AgentNode,
        'wait': WaitNode,
        'rag': RAGNode,
        'message': MessageNode,
        'tool': ToolNode,
        'memory': MemoryNode,
    }

    @staticmethod
    def create(n: Dict[str, Any]) -> BaseNode:
        """
        根据原始节点字典创建具体节点实例。
        
        Args:
            n (Dict[str, Any]): 原始节点配置（包含 id/type/data/input/output 等字段）
        
        Returns:
            BaseNode: 创建好的具体节点对象（如 StartNode/ConditionNode 等）
        """
        type_ = n.get('type') or 'unknown'
        cls = NodeFactory.TYPE_MAP.get(type_, BaseNode)
        obj = cls(id=n.get('id') or '', type_=type_, data=n.get('data') or {})
        # Populate input/output if provided in JSON; otherwise keep defaults
        input_data = n.get('input')
        output_data = n.get('output')
        if isinstance(input_data, dict):
            obj.input = input_data
        if isinstance(output_data, dict):
            obj.output = output_data
        return obj